
from rest_framework import serializers
from rest_framework_jwt.utils import jwt_payload_handler, jwt_encode_handler
from . import models
from django.core.cache import cache
from django.conf import settings
import re

class LoginModelSerializer(serializers.ModelSerializer):

    username = serializers.CharField(min_length=4, max_length=18)
    password = serializers.CharField(min_length=8, max_length=18)

    class Meta:
        model = models.User
        fields = ['username', 'password']

    def validate(self, attrs):
        # 多方式登录
        user_obj = self._many_login(**attrs)
        # 签发token
        payload = jwt_payload_handler(user_obj)
        token = jwt_encode_handler(payload)
        # 将信息保存
        self.username = user_obj.username
        self.token = token

        return attrs

    def _many_login(self, **attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        # 邮箱
        if re.match(r'.*@.*', username):
            user_obj = models.User.objects.filter(is_active=True, email=username).first()   # type: models.User
        # 手机号
        elif re.match(r'^1[3-9][0-9]{9}$', username):
            user_obj = models.User.objects.filter(is_active=True, mobile=username).first()   # type: models.User
        # 用户名
        else:
            user_obj = models.User.objects.filter(is_active=True, username=username).first()   # type: models.User
        # 用户名不存在
        if not user_obj:
            raise serializers.ValidationError({'username': ['用户名不存在']})
        # 密码错误
        if not user_obj.check_password(password):
            raise serializers.ValidationError({'password': ['密码错误']})

        return user_obj


class RegisterModelSerializer(serializers.ModelSerializer):

    mobile = serializers.CharField(min_length=11, max_length=11)
    password = serializers.CharField(min_length=8, max_length=18)
    code = serializers.CharField(min_length=6, max_length=6)

    class Meta:
        model = models.User
        fields = ['mobile', 'password', 'code']

    def validate_mobile(self, value):

        if not re.match(r'^1[3-9][0-9]{9}$', value):
            raise serializers.ValidationError('手机号码有误')
        try:
            models.User.objects.get(is_active=True, mobile=value)
        except:
            return value
        raise serializers.ValidationError('手机号已注册')

    def validate_code(self, value:str):

        if value.isdigit():
            return value
        raise serializers.ValidationError('验证码错误')

    def validate(self, attrs):
        # 获取数据
        mobile = attrs.get('mobile')
        code = attrs.pop('code')
        print(settings.SMS_KEY)
        old_code = cache.get(settings.SMS_KEY % mobile)
        # 判断数据验证码是否一致
        if code == old_code:
            cache.set(settings.SMS_KEY % mobile, '0000', 0)
            attrs['username'] = mobile
            attrs['email'] = mobile + "@luffy.com"
            return attrs
        raise serializers.ValidationError({'code': ['验证码错误']})

    def create(self, validated_data):
        return models.User.objects.create_user(**validated_data)


class LoginMobileModelSerializer(serializers.ModelSerializer):

    mobile = serializers.CharField(min_length=11, max_length=11)
    code = serializers.CharField(min_length=6, max_length=6)

    class Meta:
        model = models.User
        fields = ['mobile', 'code']

    def validate_mobile(self, value):
        if not re.match(r'^1[3-9][0-9]{9}$', value):
            raise serializers.ValidationError('手机号码有误')
        try:
            models.User.objects.get(is_active=True, mobile=value)
        except:
            raise serializers.ValidationError('手机号未注册')
        return value

    def validate_code(self, value):

        if value.isdigit():
            return value
        raise serializers.ValidationError('验证码错误')

    def validate(self, attrs):
        # 获取数据
        mobile = attrs.get('mobile')
        code = attrs.get('code')
        old_code = cache.get(settings.SMS_KEY % mobile)
        # 判断数据验证码是否一致
        if code == old_code:
            cache.set(settings.SMS_KEY % mobile, '0000', 0)
            user_obj = models.User.objects.get(mobile=mobile)
            # 签发token
            payload = jwt_payload_handler(user_obj)
            token = jwt_encode_handler(payload)
            # 将信息保存
            self.username = user_obj.username
            self.token = token

            return attrs
        raise serializers.ValidationError({'code': ['验证码错误']})
